#ifndef _LINUX_AO_DEV_H
#define _LINUX_AO_DEV_H

#include <linux/types.h>
#include "drv_pcie.h"
#include "drv_pcie_irq.h"
#include "drv_cdev.h"

/* 脉冲参数 */
struct ao_pulse_t {
    u16 high;       /* 脉冲高时间, us */
    u16 cycle;      /* 脉冲周期, us */
};

/* 电流参数 */
struct ao_current_t {
    s32 val;        /* 电流值, uA */
    u16 cycle;      /* 脉冲周期, us */
};

/* IOCTL 命令定义 */
#define IOCTL_AO_MAGIC                  'P'                                             /* 标识设备驱动 */
#define IOCTL_AO_SET_PULSE              _IOW(IOCTL_AO_MAGIC, 1, struct ao_pulse_t)      /* 配置 AO 脉冲 */

#define IOCTL_AO_GET_DRV_VERSION        _IOR(IOCTL_AO_MAGIC, 101, u32)                  /* 获取驱动版本号 */
#define IOCTL_AO_GET_FPGA_VERSION       _IOR(IOCTL_AO_MAGIC, 102, u32)                  /* 获取 FPGA 版本号 */


/* 设备 */
struct ao_dev_t {
    void *parent;               /* 父设备指针 */
    struct device *dev;         /* 设备描述符 */
    struct mutex lock;          /* 互斥锁 */
    char name[32];              /* 设备名称 */
    u8 index;                   /* 索引号 */

    u32 pulse_width;            /* 脉冲宽度, 0~50%(后放大 1000 倍) */
    struct ao_pulse_t pulse;    /* 脉冲参数 */
    struct ao_current_t curr;   /* 电流参数 */
};

/* 控制器 */
struct ao_ctrl_t {
    struct device *dev;                                                 /* 设备描述符 */
    struct mutex lock;                                                  /* 互斥锁 */
    char name[32];                                                      /* 设备名称 */
    u8 num;                                                             /* 设备数量 */

    struct pcie_dev_t *pcie_dev;                                        /* PCIe 设备指针 */
    u32 (*read_reg)(struct pcie_dev_t *pcie_dev, u32 reg);              /* 读寄存器 */
    void (*write_reg)(struct pcie_dev_t *pcie_dev, u32 reg, u32 val);   /* 写寄存器 */
    struct cdev_ctrl_t cdev_ctrl;                                       /* 字符设备 */
    struct ao_dev_t *ao;                                                /* ao */

    u32 drv_ver;                                                        /* 驱动版本号 */
    u32 fpga_ver;                                                       /* FPGA 版本号 */
};

/* 初始化 AO 控制器 */
int init_ao_ctrl(struct pcie_dev_t *pcie_dev, struct cdev_dev_t *cdev_dev, 
                 struct ao_ctrl_t *pctrl, struct ao_dev_t *ao, 
                 const char *ctrl_name, u8 dev_num);
/* 注销 AO 控制器 */
void exit_ao_ctrl(struct ao_ctrl_t *ctrl, u8 dev_num);

#endif /* _LINUX_AO_DEV_H */
